package com.agritech;

import com.agritech.facade.AgriTechSystemFacade;
import com.agritech.proxy.AgriculturalMachineProxy;
import com.agritech.proxy.MachineProxy;
import com.agritech.decorator.GPSFeatureDecorator;
import com.agritech.decorator.AutoRefuelReminderDecorator;
import com.agritech.machine.AgriculturalMachineContext;

import java.util.Map;
import java.util.Scanner;

public class Main {


    private static Scanner scanner = new Scanner(System.in);
    private static AgriTechSystemFacade systemFacade;
    private static MachineProxy harvesterProxy;
    private static MachineProxy gpsHarvester;

    public static void main(String[] args) {
        System.out.println("nihao,beibei");
    }


    private static MachineProxy smartHarvester;


    
    public static void main(String[] args) {
        System.out.println(  "智能无人驾驶农机系统启动中...");

        // 初始化系统
        initializeSystem();




        boolean running = true;
        while (running) {
            
            displayMainMenu();
            int choice = getUserChoice(0, 7);
            
            switch (choice) {
                case 1:
                    manageMachines();
                    break;
                case 2:
                    environmentMonitoring();
                    break;
                case 3:
                    machineOperations();
                    break;

                case 0:
                    running = false;
                    System.out.println("系统已关闭，感谢使用！");
                    break;
            }
        }
        scanner.close();
    }
    
    private static void initializeSystem() {
        // 1. 使用外观模式初始化系统
        systemFacade = new AgriTechSystemFacade();
        
        // 2. 初始化农机
        systemFacade.addMachine("S001", "Seeder");
        systemFacade.addMachine("H001", "Harvester");
        systemFacade.addMachine("P001", "Sprayer");
        systemFacade.addMachine("S002", "Seeder");
        
        // 3. 初始化代理和装饰器
        harvesterProxy = new AgriculturalMachineProxy("H002_Proxied", "Harvester");
        gpsHarvester = new GPSFeatureDecorator(harvesterProxy);
        smartHarvester = new AutoRefuelReminderDecorator(gpsHarvester);
    }
    
    private static void displayMainMenu() {
        System.out.println("\n========== 智能无人驾驶农机系统 ==========");
        System.out.println("1. 农机管理与创建 (工厂模式 & 观察者模式)");
        System.out.println("2. 环境监测与智能响应 (观察者模式 & 策略模式)");
        System.out.println("3. 农机远程控制 (命令模式 & 状态模式)");
        System.out.println("4. 安全事件处理 (责任链模式)");
        System.out.println("5. 农机访问控制与功能增强 (代理模式 & 装饰器模式)");
        System.out.println("6. 显示所有农机状态");
        System.out.println("7. 运行完整演示");
        System.out.println("0. 退出系统");
        System.out.print("请选择操作 (0-7): ");
    }
    
    private static int getUserChoice(int min, int max) {
        int choice = -1;
        while (choice < min || choice > max) {
            try {
                choice = Integer.parseInt(scanner.nextLine().trim());
                if (choice < min || choice > max) {
                    System.out.print("输入无效，请重新输入 (" + min + "-" + max + "): ");
                }
            } catch (NumberFormatException e) {
                System.out.print("请输入有效数字 (" + min + "-" + max + "): ");
            }
        }
        return choice;
    }
    
    private static void manageMachines() {
        System.out.println("\n--- 农机管理与创建 ---");
        System.out.println("1. 添加新农机");
        System.out.println("2. 显示所有农机状态");
        System.out.println("0. 返回主菜单");
        System.out.print("请选择操作 (0-2): ");
        
        int choice = getUserChoice(0, 2);
        switch (choice) {
            case 1:
                System.out.print("请输入农机ID: ");
                String id = scanner.nextLine().trim();
                System.out.println("请选择农机类型:");
                System.out.println("1. 播种机 (Seeder)");
                System.out.println("2. 收割机 (Harvester)");
                System.out.println("3. 喷药机 (Sprayer)");
                System.out.print("请选择 (1-3): ");
                
                int typeChoice = getUserChoice(1, 3);
                String type = "";
                switch (typeChoice) {
                    case 1: type = "Seeder"; break;
                    case 2: type = "Harvester"; break;
                    case 3: type = "Sprayer"; break;
                }
                
                systemFacade.addMachine(id, type);
                System.out.println("农机 " + id + " (" + type + ") 添加成功！");
                break;
            case 2:
                systemFacade.displayAllMachineStatuses();
                break;
        }
    }
    
    private static void environmentMonitoring() {
        System.out.println("\n--- 环境监测与智能响应 ---");
        System.out.println("1. 更新环境数据");
        System.out.println("2. 手动规划路径");
        System.out.println("0. 返回主菜单");
        System.out.print("请选择操作 (0-2): ");
        
        int choice = getUserChoice(0, 2);
        switch (choice) {
            case 1:
                System.out.println("请选择环境数据类型:");
                System.out.println("1. 土壤湿度过高");
                System.out.println("2. 检测到障碍物");
                System.out.println("3. 自定义环境数据");
                System.out.print("请选择 (1-3): ");
                
                int dataChoice = getUserChoice(1, 3);
                String data = "";
                switch (dataChoice) {
                    case 1: data = "农田区域A 土壤湿度过高"; break;
                    case 2: data = "农田区域B 检测到小型障碍物"; break;
                    case 3: 
                        System.out.print("请输入自定义环境数据: ");
                        data = scanner.nextLine().trim();
                        break;
                }
                
                systemFacade.updateEnvironmentData(data);
                break;
            case 2:
                System.out.print("请输入农机ID: ");
                String id = scanner.nextLine().trim();
                System.out.print("请输入路径规划信息: ");
                String info = scanner.nextLine().trim();
                
                systemFacade.planPathForMachine(id, info);
                break;
        }
    }
    
    private static void machineOperations() {
        System.out.println("\n--- 农机远程控制 ---");
        System.out.println("1. 启动农机");
        System.out.println("2. 农机开始作业");
        System.out.println("3. 停止农机");
        System.out.println("4. 撤销上一次操作");
        System.out.println("5. 查看农机状态");
        System.out.println("6. 模拟油料耗尽场景");
        System.out.println("7. 维修农机(加油)");
        System.out.println("0. 返回主菜单");
        System.out.print("请选择操作 (0-7): ");
        
        int choice = getUserChoice(0, 7);
        if (choice >= 1 && choice <= 3 || choice == 5 || choice == 7) {
            System.out.print("请输入农机ID: ");
            String id = scanner.nextLine().trim();
            
            switch (choice) {
                case 1:
                    systemFacade.startMachineOperation(id);
                    break;
                case 2:
                    systemFacade.workMachineOperation(id);
                    break;
                case 3:
                    systemFacade.stopMachineOperation(id);
                    break;
                case 5:
                    systemFacade.getMachineStatus(id);
                    break;
                case 7:
                    System.out.println("模拟维修" + id + "...");
                    AgriculturalMachineContext context = getMachineContextDirectly(id, systemFacade);
                    if (context != null) {
                        context.fix();
                        System.out.println(id + "已维修完成（加油）");
                        systemFacade.getMachineStatus(id);
                    } else {
                        System.out.println("找不到农机: " + id);
                    }
                    break;
            }
        } else if (choice == 4) {
            systemFacade.undoLastMachineOperation();
        } else if (choice == 6) {
            System.out.print("请输入要模拟油料耗尽的农机ID: ");
            String id = scanner.nextLine().trim();
            System.out.println("模拟" + id + "多次作业消耗油料...");
            
            for (int i = 0; i < 10; i++) {
                String result = systemFacade.workMachineOperation(id);
                systemFacade.getMachineStatus(id);
                
                AgriculturalMachineContext machine = getMachineContextDirectly(id, systemFacade);
                if (machine != null && machine.getCurrentState().getStateName().equals("油料耗尽")) {
                    System.out.println(id + "油料耗尽，停止作业。");
                    break;
                }
                if (result.contains("油料耗尽")) break;
            }
        }
    }
    
    private static void safetyEventHandling() {
        System.out.println("\n--- 安全事件处理 ---");
        System.out.println("1. 报告障碍物检测");
        System.out.println("2. 报告设备故障");
        System.out.println("3. 报告油量低");
        System.out.println("4. 自定义安全事件");
        System.out.println("0. 返回主菜单");
        System.out.print("请选择操作 (0-4): ");
        
        int choice = getUserChoice(0, 4);
        if (choice >= 1 && choice <= 4) {
            String eventType = "";
            String details = "";
            
            switch (choice) {
                case 1:
                    eventType = "OBSTACLE_DETECTED";
                    System.out.print("请输入障碍物详情: ");
                    details = scanner.nextLine().trim();
                    break;
                case 2:
                    eventType = "DEVICE_FAULT_DETECTED";
                    System.out.print("请输入故障详情: ");
                    details = scanner.nextLine().trim();
                    break;
                case 3:
                    eventType = "LOW_FUEL";
                    System.out.print("请输入油量低详情: ");
                    details = scanner.nextLine().trim();
                    break;
                case 4:
                    System.out.print("请输入事件类型: ");
                    eventType = scanner.nextLine().trim();
                    System.out.print("请输入事件详情: ");
                    details = scanner.nextLine().trim();
                    break;
            }
            
            systemFacade.reportSafetyEvent(eventType, details);
        }
    }
    
    private static void proxyAndDecoratorDemo() {
        System.out.println("\n--- 农机访问控制与功能增强 ---");
        System.out.println("1. 管理员操作普通代理农机");
        System.out.println("2. 操作员操作普通代理农机");
        System.out.println("3. 管理员操作增强农机(GPS+油量提醒)");
        System.out.println("0. 返回主菜单");
        System.out.print("请选择操作 (0-3): ");
        
        int choice = getUserChoice(0, 3);
        if (choice >= 1 && choice <= 3) {
            System.out.println("请选择操作类型:");
            System.out.println("1. 显示状态");
            System.out.println("2. 启动农机");
            System.out.println("3. 开始作业");
            System.out.println("4. 停止农机");
            System.out.print("请选择 (1-4): ");
            
            int opChoice = getUserChoice(1, 4);
            String user = (choice == 2) ? "operator1" : "admin";
            MachineProxy proxy = (choice == 3) ? smartHarvester : harvesterProxy;
            
            switch (opChoice) {
                case 1:
                    proxy.displayStatus(user);
                    break;
                case 2:
                    proxy.startOperation(user);
                    break;
                case 3:
                    proxy.workOperation(user);
                    break;
                case 4:
                    proxy.stopOperation(user);
                    break;
            }
        }
    }
    
    private static void runFullDemo() {
        System.out.println("\n========== 运行完整演示 ==========");
        
        // 1. 显示所有农机初始状态
        System.out.println("\n--- 1. 农机管理与创建 (工厂模式 & 观察者模式自动注册) ---");
        systemFacade.displayAllMachineStatuses();

        // 2. 模拟环境变化，触发观察者模式和策略模式
        System.out.println("\n--- 2. 环境监测与智能响应 (观察者模式 & 策略模式) ---");
        systemFacade.updateEnvironmentData("农田区域A 土壤湿度过高");
        systemFacade.updateEnvironmentData("农田区域B 检测到小型障碍物");
        systemFacade.planPathForMachine("S001", "S001区域一切正常，请求标准路径");

        // 3. 农机操作 (命令模式，通过外观调用)
        System.out.println("\n--- 3. 农机远程控制 (命令模式 & 状态模式) ---");
        systemFacade.startMachineOperation("S001");
        systemFacade.workMachineOperation("S001");
        systemFacade.workMachineOperation("S001");
        systemFacade.getMachineStatus("S001");
        systemFacade.stopMachineOperation("S001");
        systemFacade.undoLastMachineOperation();
        systemFacade.getMachineStatus("S001");
        
        // 模拟油料耗尽
        System.out.println("模拟S001多次作业消耗油料...");
        for(int i=0; i<10; i++) {
            String result = systemFacade.workMachineOperation("S001");
            systemFacade.getMachineStatus("S001");
            AgriculturalMachineContext machine = getMachineContextDirectly("S001", systemFacade);
            if (machine != null && machine.getCurrentState().getStateName().equals("油料耗尽")) {
                System.out.println("S001油料耗尽，停止作业。");
                break;
            }
            if (result.contains("油料耗尽")) break;
        }
        
        // 尝试对油料耗尽的农机进行操作
        systemFacade.startMachineOperation("S001");
        
        // 模拟维修
        System.out.println("模拟维修S001...");
        AgriculturalMachineContext s001_context = getMachineContextDirectly("S001", systemFacade);
        if(s001_context != null && s001_context.getCurrentState().getStateName().equals("油料耗尽")){
            s001_context.fix();
        }
        systemFacade.getMachineStatus("S001");

        // 4. 安全事件处理
        System.out.println("\n--- 4. 安全事件处理 (责任链模式) ---");
        systemFacade.reportSafetyEvent("OBSTACLE_DETECTED", "前方发现大型固定障碍物");
        systemFacade.reportSafetyEvent("DEVICE_FAULT_DETECTED", "H001号收割机引擎温度过高 (严重)");
        systemFacade.reportSafetyEvent("LOW_FUEL", "P001号喷药机油量低 (非责任链处理，由状态模式或装饰器处理)");

        // 5. 代理模式与装饰器模式演示
        System.out.println("\n--- 5. 农机访问控制与功能增强 (代理模式 & 装饰器模式) ---");
        
        // 使用admin用户操作
        System.out.println("\n管理员(admin)操作 H002_Proxied:");
        harvesterProxy.displayStatus("admin");
        harvesterProxy.startOperation("admin");
        harvesterProxy.workOperation("admin");
        harvesterProxy.stopOperation("admin");

        // 使用普通操作员用户操作
        System.out.println("\n操作员(operator1)操作 H002_Proxied:");
        harvesterProxy.displayStatus("operator1");
        harvesterProxy.startOperation("operator1");
        harvesterProxy.workOperation("operator1");
        harvesterProxy.stopOperation("operator1");

        // 使用装饰器增强代理对象
        System.out.println("\n管理员(admin)操作增强后的 H002_Proxied:");
        smartHarvester.displayStatus("admin");
        smartHarvester.startOperation("admin");
        smartHarvester.workOperation("admin");

        System.out.println("\n--- 系统演示结束 ---");
        systemFacade.displayAllMachineStatuses();
    }

    // 辅助方法，实际项目中不应该这样直接从Facade获取内部对象，这里仅为演示状态模式的fix
    private static AgriculturalMachineContext getMachineContextDirectly(String machineId, AgriTechSystemFacade facade) {
        // This is a HACK for demonstration. In a real system, facade would provide proper methods.
        // Or the fix operation itself would be part of the facade or command pattern.
        try {
            java.lang.reflect.Field machinesField = AgriTechSystemFacade.class.getDeclaredField("machines");
            machinesField.setAccessible(true);
            java.util.Map<String, AgriculturalMachineContext> machines = (java.util.Map<String, AgriculturalMachineContext>) machinesField.get(facade);
            return machines.get(machineId);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}